package br.com.future.dao;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import br.com.future.bo.ProcessoBO;
import br.com.future.dao.interfaces.TituloDAOI;
import br.com.future.jdbc.ConnectionFactory;
import br.com.future.model.Advogado;
import br.com.future.model.Processo;
import br.com.future.model.TipoCobranca;
import br.com.future.model.Titulo;

public class TituloDAO implements TituloDAOI {

	private Connection conn = null;
	private boolean flag = true;
	private Calendar calendar = null;

	public TituloDAO(Connection conn) {
		this.conn = conn;
	}

	public TituloDAO() {

	}

	public Titulo consultar(int numeroTitulo) {

		verificarInstanciaDeConnection();
		String sql = "SELECT NR_TITULO, NR_PROCESSO, NR_AGENCIA_CEDENTE, DT_DOCUMENTO, DT_VENCIMENTO, VL_DOCUMENTO FROM AM_TITULO "
				+ "FROM AM_PROCESSO PROCESSO"
				+ "INNER JOIN AM_TITULO TITULO ON TITULO.NR_PROCESSO = PROCESSO.NR_PROCESSO"
				+ "FROM AM_PROCESSO PROC"
				+ "INNER JOIN AM_TIPO_COBRANCA COBRANCA ON PROC.CD_COBRANCA = PROCESSO.CD_COBRANCA"
				+ " WHERE NR_TITULO = ?";
		PreparedStatement ps = null;
		ResultSet rs = null;
		Titulo titulo = new Titulo();

		try {

			ps = conn.prepareStatement(sql);
			ps.setInt(1, numeroTitulo);
			rs = ps.executeQuery();
			if (rs.next()) {
				titulo.setNumeroTitulo(rs.getInt("NR_TITULO"));
				List<Advogado> advogados = new AdvogadoDAO().consultarProcessoAdvogado(rs.getLong("NR_PROCESSO"));
				Processo processo = new ProcessoDAO().consultar(rs.getLong("NR_PROCESSO"));
				processo.setDescricaoObservacao(rs.getString("DS_OBSERVACAO"));
				
				processo.setAdvogados(advogados);
				TipoCobranca cobranca = new TipoCobrancaDAO().consultarPorId(rs.getInt("CD_COBRANCA"));
				processo.setTipoCobranca(cobranca);
				
				titulo.setProcesso(processo);
				titulo.setNumeroAgenciaCedente(rs.getInt("NR_AGENCIA_CEDENTE"));

				calendar.setTime(rs.getDate("DT_DOCUMENTO"));
				titulo.setDataDocumento(calendar);
				calendar.setTime(rs.getDate("DT_VENCIMENTO"));
				titulo.setDataVencimento(calendar);
				titulo.setValorDocumento(rs.getDouble("VL_DOCUMENTO"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (flag) {
				ConnectionFactory.closeConnectionOracle(conn, rs, ps);
			}
		}
		return titulo;
	}

	public List<Titulo> consultar() {
		
		verificarInstanciaDeConnection();

		String sql = "SELECT TITULO.NR_TITULO, PROCESSO.NR_PROCESSO, TITULO.NR_AGENCIA_CEDENTE, TITULO.DT_DOCUMENTO," +
				" TITULO.DT_VENCIMENTO, TITULO.VL_DOCUMENTO, COBRANCA.CD_COBRANCA, COBRANCA.DS_COBRANCA " +
				" FROM AM_PROCESSO PROCESSO " +
				"INNER JOIN AM_TITULO TITULO ON " +
				"TITULO.NR_PROCESSO = PROCESSO.NR_PROCESSO" +
				" INNER JOIN AM_TIPO_COBRANCA COBRANCA ON " +
				" COBRANCA.CD_COBRANCA = PROCESSO.CD_COBRANCA";

		PreparedStatement ps = null;

		ResultSet rs = null;

		List<Titulo> listaTitulo = new ArrayList<Titulo>();
		
		try {

			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();

			while (rs.next()) {
				calendar = Calendar.getInstance();
				Titulo titulo = new Titulo();
				titulo.setNumeroAgenciaCedente(rs.getInt("NR_AGENCIA_CEDENTE"));
				Processo processo = ProcessoBO.consultarProcessoPorNrProc(rs.getLong("NR_PROCESSO"));
				List<Advogado> advogados = new AdvogadoDAO().consultarProcessoAdvogado(rs.getLong("NR_PROCESSO"));
				processo.setAdvogados(advogados);
				TipoCobranca tpCobranca = new TipoCobranca();
				tpCobranca.setCodigoCobranca(rs.getInt("CD_COBRANCA"));
				tpCobranca.setDescricaoCobranca(rs.getString("DS_COBRANCA"));
				processo.setTipoCobranca(tpCobranca);
				titulo.setProcesso(processo);
				
				calendar.setTime(rs.getDate("DT_DOCUMENTO"));
				titulo.setDataDocumento(calendar);
				calendar.setTime(rs.getDate("DT_VENCIMENTO"));
				titulo.setDataVencimento(calendar);
				titulo.setValorDocumento(rs.getDouble("VL_DOCUMENTO"));
				listaTitulo.add(titulo);
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (flag) {
				ConnectionFactory.closeConnectionOracle(conn, rs, ps);
			}
		}

		return listaTitulo;
	}
	
	public List<Titulo> consultarBloqueados() {
		
		verificarInstanciaDeConnection();

		String sql ="SELECT HIST.NR_PROCESSO, HIST.DT_BLOQUEIO_DESBLOQ, COBRANCA.CD_COBRANCA," +
					"       COBRANCA.DS_COBRANCA, BLOQ.CD_BLOQUEIO_DESBLOQ, BLOQ.DS_BLOQUEIO_DESBLOQ" +
					" FROM AM_HIST_PROC_BLOQ_DESBLOQ HIST" +
					" INNER JOIN AM_PROCESSO PROCESSO ON" +
					" 	  PROCESSO.NR_PROCESSO = HIST.NR_PROCESSO" +
					" INNER JOIN AM_TIPO_COBRANCA COBRANCA ON" +
					" 	  COBRANCA.CD_COBRANCA = PROCESSO.CD_COBRANCA" +
					" INNER JOIN AM_BLOQUEIO_DESBLOQ BLOQ ON" +
					" 	  BLOQ.CD_BLOQUEIO_DESBLOQ = HIST.CD_BLOQUEIO_DESBLOQ" +
					" ORDER BY HIST.DT_BLOQUEIO_DESBLOQ DESC;";

		PreparedStatement ps = null;

		ResultSet rs = null;
		
		List<Titulo> listaTitulo = new ArrayList<Titulo>();
		
		try {

			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();

			while (rs.next()) {
				calendar = Calendar.getInstance();
				Titulo titulo = new Titulo();
				titulo.setNumeroAgenciaCedente(rs.getInt("NR_AGENCIA_CEDENTE"));
				Processo processo = ProcessoBO.consultarProcessoPorNrProc(rs.getLong("NR_PROCESSO"));
				List<Advogado> advogados = new AdvogadoDAO().consultarProcessoAdvogado(rs.getLong("NR_PROCESSO"));
				processo.setAdvogados(advogados);
				TipoCobranca tpCobranca = new TipoCobranca();
				tpCobranca.setCodigoCobranca(rs.getInt("CD_COBRANCA"));
				tpCobranca.setDescricaoCobranca(rs.getString("DS_COBRANCA"));
				processo.setTipoCobranca(tpCobranca);
				titulo.setProcesso(processo);
				
				calendar.setTime(rs.getDate("DT_DOCUMENTO"));
				titulo.setDataDocumento(calendar);
				calendar.setTime(rs.getDate("DT_VENCIMENTO"));
				titulo.setDataVencimento(calendar);
				titulo.setValorDocumento(rs.getDouble("VL_DOCUMENTO"));
				listaTitulo.add(titulo);
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (flag) {
				ConnectionFactory.closeConnectionOracle(conn, rs, ps);
			}
		}

		return listaTitulo;
	}
	
		
	
	public void alterarTitulo(Titulo titulo){
		verificarInstanciaDeConnection();
		
		String sql = "UPDATE AM_TITULO SET CD_TITULO = ?,DD_DATA_VENCIMENTO = ? WHERE NR_TITULO = ?";
		PreparedStatement ps = null;
		
		try {
			ps = conn.prepareStatement(sql);
			ps.setLong(1,titulo.getProcesso().getNumeroProcesso());
			ps.setDate(2,new Date(titulo.getDataVencimento().getTimeInMillis()));
			ps.setLong(3, titulo.getNumeroTitulo());
			
			ps.executeUpdate();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			if(flag){
				ConnectionFactory.closeConnectionOracle(conn, ps);
			}
		}
	}

	private void verificarInstanciaDeConnection() {
		flag = true;

		if (conn == null) {
			conn = ConnectionFactory.getConnection();
		} else {
			flag = false;
		}
	}

}
